﻿namespace Stopwatch.Controls
{
    using Microsoft.Phone.Controls.Primitives;
    using System;
    using System.Collections.Generic;
    using System.Threading;
    using System.Windows;
    using System.Windows.Controls;

    public partial class TimerControl : UserControl
    {
        const int WarningInterval = 500;

        Queue<Timer> timers = new Queue<Timer>();

        public TimerControl()
        {
            Mode = TimerMode.Picker;
            InitializeComponent();
            HoursLoopingSelector.IsExpandedChanged += OnSelectorIsExpandedChanged;
            MinutesLoopingSelector.IsExpandedChanged += OnSelectorIsExpandedChanged;
            SecondsLoopingSelector.IsExpandedChanged += OnSelectorIsExpandedChanged;

            (HoursLoopingSelector.DataSource as NumbersDataSource).SelectionChanged += HourSelectionChanged;
            (MinutesLoopingSelector.DataSource as NumbersDataSource).SelectionChanged += MinuteSelectionChanged;
            (SecondsLoopingSelector.DataSource as NumbersDataSource).SelectionChanged += SecondSelectionChanged;
        }

        private void OnSelectorIsExpandedChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            if ((bool)e.NewValue)
            {
                var selector = sender as LoopingSelector;

                // Ensure that only one selector is expanded at a time
                HoursLoopingSelector.IsExpanded = (selector == HoursLoopingSelector);
                MinutesLoopingSelector.IsExpanded = (selector == MinutesLoopingSelector);
                SecondsLoopingSelector.IsExpanded = (selector == SecondsLoopingSelector);

                hoursTag.Visibility = HoursLoopingSelector.IsExpanded ?
                    System.Windows.Visibility.Collapsed : System.Windows.Visibility.Visible;

                minutesTag.Visibility = MinutesLoopingSelector.IsExpanded ?
                    System.Windows.Visibility.Collapsed : System.Windows.Visibility.Visible;

                secondsTag.Visibility = SecondsLoopingSelector.IsExpanded ?
                    System.Windows.Visibility.Collapsed : System.Windows.Visibility.Visible;

            }
        }

        private void HourSelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            hours.Text = (sender as NumbersDataSource).SelectedItem.ToString();
        }

        private void MinuteSelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            minutes.Text = (sender as NumbersDataSource).SelectedItem.ToString();
        }

        private void SecondSelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            seconds.Text = (sender as NumbersDataSource).SelectedItem.ToString();
        }

        /// <summary>
        /// show warning...
        /// </summary>
        public void Warning()
        {
            // timers.Enqueue(new Timer(WarningEffect, "false", WarningInterval, WarningInterval));
        }

        void WarningEffect(object state)
        {
            switch ((string)state)
            {
                case "false":
                    state = "true";
                    this.Dispatcher.BeginInvoke(() =>
                    {
                        foreach (var c in ShowPanel.Children)
                        {
                            c.Visibility = System.Windows.Visibility.Collapsed;
                        }
                    });
                    break;
                case "true":
                default:
                    var timer = timers.Dequeue();
                    timer.Change(Timeout.Infinite, Timeout.Infinite);
                    timer.Dispose();
                    this.Dispatcher.BeginInvoke(() =>
                    {
                        foreach (var c in ShowPanel.Children)
                        {
                            c.Visibility = System.Windows.Visibility.Visible;
                        }
                    });
                    break;
            }
        }

        public Time TimerDuration { get { return new Time(int.Parse(hours.Text), int.Parse(minutes.Text), int.Parse(seconds.Text)); } }

        #region Hours
        public static readonly DependencyProperty HoursProperty = DependencyProperty.Register("Hours", typeof(int), typeof(TimerControl), new PropertyMetadata(OnHoursChanged));

        static void OnHoursChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
        {
            int value = (int)args.NewValue;
            (obj as TimerControl).hours.Text = value.ToString("D2");
        }

        public int Hours
        {
            get { return (int)GetValue(HoursProperty); }
            set { SetValue(HoursProperty, value); }
        }
        #endregion

        #region Minutes
        public static readonly DependencyProperty MinutesProperty = DependencyProperty.Register("Minutes", typeof(int), typeof(TimerControl), new PropertyMetadata(OnMinutesChanged));

        static void OnMinutesChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
        {
            int value = (int)args.NewValue;
            (obj as TimerControl).minutes.Text = value.ToString("D2");
        }
        public int Minutes
        {
            get { return (int)GetValue(MinutesProperty); }
            set
            {
                SetValue(MinutesProperty, value);
            }
        }
        #endregion

        #region Seconds
        public static readonly DependencyProperty SecondsProperty = DependencyProperty.Register("Seconds", typeof(int), typeof(TimerControl), new PropertyMetadata(OnSecondsChanged));

        static void OnSecondsChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
        {
            int value = (int)args.NewValue;
            (obj as TimerControl).seconds.Text = value.ToString("D2");
        }
        public int Seconds
        {
            get { return (int)GetValue(SecondsProperty); }
            set
            {
                SetValue(SecondsProperty, value);
            }
        }
        #endregion

        #region Mode
        public static readonly DependencyProperty ModeProperty = DependencyProperty.Register("Mode", typeof(TimerMode), typeof(TimerControl), new PropertyMetadata(OnModeChanged));

        static void OnModeChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
        {
            TimerControl control = obj as TimerControl;
            TimerMode mode = (TimerMode)args.NewValue;
            switch (mode)
            {
                case Controls.TimerMode.Picker:
                    control.ShowPanel.Visibility = System.Windows.Visibility.Collapsed;
                    control.PickerPanel.Visibility = System.Windows.Visibility.Visible;
                    control.hours.Text = control.HoursLoopingSelector.DataSource.SelectedItem.ToString();
                    control.minutes.Text = control.MinutesLoopingSelector.DataSource.SelectedItem.ToString();
                    control.seconds.Text = control.SecondsLoopingSelector.DataSource.SelectedItem.ToString();
                    break;

                case Controls.TimerMode.Show:
                    control.PickerPanel.Visibility = System.Windows.Visibility.Collapsed;
                    control.ShowPanel.Visibility = System.Windows.Visibility.Visible;
                    break;
            }
        }

        public TimerMode Mode
        {
            get { return (TimerMode)GetValue(ModeProperty); }
            set
            {
                SetValue(ModeProperty, value);
            }
        }
        #endregion

    }
}
